<?php
use think\facade\Cookie;

// 应用公共文件
/**
 * 数组转对象
 * @param $array
 * @return StdClass
 */
function array2object($array)
{
    if (is_array($array)) {
        $obj = new StdClass();
        foreach ($array as $key => $val) {
            $obj->$key = $val;
        }
    } else {
        $obj = $array;
    }
    return $obj;
}


/**对象转数组
 * @param $object
 * @return array
 */
function object2array($object)
{
    $array = [];
    if (is_object($object)) {
        foreach ($object as $key => $value) {
            $array[$key] = $value;
        }
    } else {
        $array = $object;
    }
    return $array;
}


/**
 * 数组转换为JSON
 * @param array $array 数组
 * @return string
 */
function array2json($array = [])
{
    if (!is_array($array) || empty($array)) {
        return '';
    }
    return json_encode($array, JSON_UNESCAPED_UNICODE);
}

/**
 * JSON转换为数组
 * @param string $string JSON字符串
 * @return array|mixed
 */
function json2array($string = '')
{
    if (empty($string)) {
        return [];
    }
    if (!is_string($string)) {
        return [];
    }
    return json_decode($string, true);
}

/**
 * 把表中的数据生成缓存
 * @param mixed $name 缓存名称
 * @param mixed $value 缓存值
 * @param mixed $options 缓存参数
 * @return mixed
 */
function getCache($name, $value = '', $options = [])
{
    if ($value) {
        cache($name, $value);//生成缓存
        return true;
    }
    // 读取缓存
    $data = cache($name);
    // 如果缓存为空，则重新生成缓存
    if (empty($data)) {
        $pk = isset($options['pk']) ? $options['pk'] : 'id';
        $order = isset($options['order']) ? $options['order'] : $pk . ' asc';
        $where = isset($options['where']) ? $options['where'] : [];
        $data = \think\Db::name($name)->where($where)->order($order)->column('*', $pk);//查询数据
        cache($name, $data);//生成缓存
    }
    return $data;
}

/*
 * 把redis中的数据表数据
 */
function getTableCache($name, $value = '', $options = [])
{
    $redis = getRedis();
    $key = 'table:' . $name;
    if ($value) {
        //生成缓存
        $redis->set($key, is_array($value) ? array2json($value) : $value);
        return true;
    }
    // 读取缓存
    $data = $redis->get($key);
    // 如果缓存为空，则重新生成缓存
    if (empty($data)) {
        $pk = isset($options['pk']) ? $options['pk'] : 'id';
        $order = isset($options['order']) ? $options['order'] : $pk . ' asc';
        $where = isset($options['where']) ? $options['where'] : [];
        $data = \think\Db::name($name)->where($where)->order($order)->column('*', $pk);//查询数据
        $redis->set($key, array2json($data));//生成缓存
        return $data;
    } else {
        return json2array($data);
    }

}


/**
 * @param int $time
 * @param int $type
 * @return bool|string
 */
function formatTime($time, $type = 's')
{
    $time = intval($time);
    if ($time < 9999999) {
        return '';
    }
    switch ($type) {
        case 's':
            $timestr = date('Y-m-d H:i:s', $time);
            break;
        case 'i':
            $timestr = date('Y-m-d H:i', $time);
            break;
        case 'h':
            $timestr = date('Y-m-d H', $time);
            break;
        case 'd':
            $timestr = date('Y-m-d', $time);
            break;
        case 'm':
            $timestr = date('Y-m', $time);
            break;
        case 'y':
            $timestr = date('Y', $time);
            break;
        default;
            $timestr = date('Y-m-d H:i:s', $time);
            break;
    }
    return $timestr;
}


/**
 * 数字格式化
 * @param $float
 * @param int $num
 * @return string
 */
function formatNumber($float, $num = 2)
{
    return number_format(floatval($float), $num, '.', '');
}

/**
 * 文本区域转换
 *
 * @param unknown $str
 * @return mixed
 */
function areatext2html($str)
{
    $str = htmlspecialchars($str);
    $str = str_replace("\r\n", "<br>", $str);
    $str = str_replace("\r", "<br>", $str);
    $str = str_replace("\n", "<br>", $str);

    return $str;
}

/**
 * 还原文本区域转换
 *
 * @param unknown $str
 * @return mixed
 */
function html2areatext($str)
{
    $str = str_replace("<br>", "\r\n", $str);
    $str = htmlspecialchars_decode($str);
    return $str;
}


/**
 * 在线生成缩略图
 * 缩略图存放路径
 *
 * @param unknown $imgurl 要生成的图片地址
 * @param number $width 缩略图宽度
 * @param number $height 缩略图高度
 * @param string $smallpic 默认图片
 * @param string $alt 图片说明
 * @return string
 */
function getThumb($imgurl, $width = 100, $height = 100, $smallpic = 'empty.jpg')
{
    //如果源图片地址为空，则返回默认空图片
    if (empty($imgurl)) {
        return '/static/images/' . $smallpic;
    }
    if (false === strpos($imgurl, 'http')) {
        $config = config('zzcms.oss_info');
        return $config['url'] . $imgurl . '?x-oss-process=image/resize,m_fill,h_' . $height . ',w_' . $width;
    } else {
        return $imgurl . '?x-oss-process=image/resize,m_fill,h_' . $height . ',w_' . $width;
    }
}

/**
 * 获取URL,计算参数,单选
 * @param $url
 * @param array $param
 */
function getParamUrl($params = [], $url = '')
{
    $request = app('request');
    $get = $request->param();
    $action = $request->action();
    foreach ($get as $urlparam => $value) {
        if (strpos($urlparam, $action)) {
            unset($get[$urlparam]);
            break;
        }
    }
    if (is_array($params)) {
        $get = array_merge($get, $params);
    }
    return urldecode(url($url ?: $action, $get));
}

/**
 * 字符截取
 * @param $string 需要截取的字符串
 * @param $length 长度
 * @param
 *   $dot
 */
function strCut($sourcestr, $length, $dot = '...')
{
    $returnstr = '';
    $i = 0;
    $n = 0;
    $str_length = strlen($sourcestr); // 字符串的字节数
    while (($n < $length) && ($i <= $str_length)) {
        $temp_str = substr($sourcestr, $i, 1);
        $ascnum = Ord($temp_str); // 得到字符串中第$i位字符的ascii码
        if ($ascnum >= 224) { // 如果ASCII位高与224，
            $returnstr = $returnstr . substr($sourcestr, $i, 3); // 根据UTF-8编码规范，将3个连续的字符计为单个字符
            $i = $i + 3; // 实际Byte计为3
            $n++; // 字串长度计1
        } elseif ($ascnum >= 192) { // 如果ASCII位高与192，
            $returnstr = $returnstr . substr($sourcestr, $i, 2); // 根据UTF-8编码规范，将2个连续的字符计为单个字符
            $i = $i + 2; // 实际Byte计为2
            $n++; // 字串长度计1
        } elseif ($ascnum >= 65 && $ascnum <= 90) { // 如果是大写字母，
            $returnstr = $returnstr . substr($sourcestr, $i, 1);
            $i = $i + 1; // 实际的Byte数仍计1个
            $n++; // 但考虑整体美观，大写字母计成一个高位字符
        } else { // 其他情况下，包括小写字母和半角标点符号，
            $returnstr = $returnstr . substr($sourcestr, $i, 1);
            $i = $i + 1; // 实际的Byte数计1个
            $n = $n + 0.5; // 小写字母和半角标点等与半个高位字符宽...
        }
    }
    if ($str_length > strlen($returnstr)) {
        $returnstr = $returnstr . $dot; // 超过长度时在尾处加上省略号
    }
    return $returnstr;
}


/**
 * 随机字符
 * @param int $length 长度
 * @param string $type 类型
 * @param int $convert 转换大小写 1大写 0小写
 * @return string
 */
function random($length = 10, $type = 'letter', $convert = 0)
{
    $config = [
        'number' => '1234567890',
        'letter' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        'string' => 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789',
        'all' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
    ];

    if (!isset($config[$type])) $type = 'letter';
    $string = $config[$type];
    $code = '';
    $strlen = strlen($string) - 1;
    for ($i = 0; $i < $length; $i++) {
        //字符串中的随机字符
        $code .= $string{mt_rand(0, $strlen)};
    }
    switch (intval($convert)) {
        case 1:
            $code = strtolower($code);
            break;
        case 2:
            $code = strtoupper($code);
            break;
        default:
    }
    return $code;
}


/**
 * 所有用到的密码加密方式
 * @param $password  密码
 * @param $password_code 密码额外加密字符
 * @return string
 */
function zzcmsPassword($password, $password_code)
{
    return md5(md5($password) . md5($password_code));
}

/**
 * 获取redis实例
 * @return \app\common\controller\Redis
 */
function getRedis($option = [])
{
    global $redis;
    if (empty($redis)) {
        $redis = new \app\common\controller\Redis($option);
    }
    return $redis;
}

/**
 * URL base64解码
 * '-' -> '+'
 * '_' -> '/'
 * 字符串长度%4的余数，补'='
 * @param unknown $string
 */
function urlsafeBase64Decode($string)
{
    $data = str_replace(array('-', '_'), array('+', '/'), $string);
    $mod4 = strlen($data) % 4;
    if ($mod4) {
        $data .= substr('====', $mod4);
    }
    return base64_decode($data);
}

/**
 * URL base64编码
 * '+' -> '-'
 * '/' -> '_'
 * '=' -> ''
 * @param unknown $string
 */
function urlsafeBase64Encode($string)
{
    $data = base64_encode($string);
    $data = str_replace(array('+', '/', '='), array('-', '_', ''), $data);
    return $data;
}

/**
 * 下载远程图片
 * @param $url  图片地址
 * @param $filename  保存的文件名（相对于网站根目录）
 * @return bool
 */
function downloadImage($url, $filename)
{
    if (empty($filename)) {
        return false;
    }
    if (false === strpos($url, 'http')) {
        return false;
    }
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_TIMEOUT, 6);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $content = curl_exec($ch);
    curl_close($ch);
    if (!$content) {
        return false;
    }
    $filename_array = explode('/', $filename);
    $dir = str_replace(end($filename_array), '', $filename);
    if (!is_dir($dir)) {
        @mkdir($dir, 0777, true);
    }
    $resource = fopen($filename, 'a');
    fwrite($resource, $content);
    fclose($resource);
    return is_file($filename);
}

/**
 * 获取远程图片的宽高和体积大小
 * @param string $url 远程图片的链接
 * @param string $type 获取远程图片资源的方式, 默认为 curl 可选 fread
 * @param boolean $isGetFilesize 是否获取远程图片的体积大小, 默认false不获取, 设置为 true 时 $type 将强制为 fread
 * @return false|array
 */
function getImageInfo($url, $type = 'curl', $isGetFilesize = false)
{
    // 若需要获取图片体积大小则默认使用 fread 方式
    $type = $isGetFilesize ? 'fread' : $type;
    if ($type == 'fread') {
        // 或者使用 socket 二进制方式读取, 需要获取图片体积大小最好使用此方法
        $handle = fopen($url, 'rb');
        if (!$handle) {
            return false;
        }
        // 只取头部固定长度168字节数据
        $dataBlock = fread($handle, 168);
    } else {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);// 超时设置
        curl_setopt($ch, CURLOPT_RANGE, '0-167');// 取前面 168 个字符 通过四张测试图读取宽高结果都没有问题,若获取不到数据可适当加大数值
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// 跟踪301跳转
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);// 返回结果
        $dataBlock = curl_exec($ch);
        curl_close($ch);
        if (!$dataBlock) {
            return false;
        }
    }
    // 将读取的图片信息转化为图片路径并获取图片信息,经测试,这里的转化设置 jpeg 对获取png,gif的信息没有影响,无须分别设置
    // 有些图片虽然可以在浏览器查看但实际已被损坏可能无法解析信息
    $size = getimagesize('data://image/jpeg;base64,' . base64_encode($dataBlock));
    if (empty($size)) {
        return false;
    }
    $result['width'] = $size[0];
    $result['height'] = $size[1];
    $result['image_type'] = $size['mime'];
    // 是否获取图片体积大小
    if ($isGetFilesize) {
        $meta = stream_get_meta_data($handle);// 获取文件数据流信息
        // nginx 的信息保存在 headers 里，apache 则直接在 wrapper_data
        $dataInfo = isset($meta['wrapper_data']['headers']) ? $meta['wrapper_data']['headers'] : $meta['wrapper_data'];
        foreach ($dataInfo as $va) {
            if (preg_match('/length/iU', $va)) {
                $ts = explode(':', $va);
                $result['size'] = trim(array_pop($ts));
                break;
            }
        }
    }
    if ($type == 'fread') {
        fclose($handle);
    }
    return $result;
}

/**
 * emjor表情反转译
 * @param $str
 * @return mixed
 */
function emojiDecode($str)
{
    $strDecode = preg_replace_callback('|\[\[EMOJI:(.*?)\]\]|', function ($matches) {
        return rawurldecode($matches[1]);
    }, $str);
    return $strDecode;
}

/**
 * emjor表情转译
 * @param $str
 * @return string
 */
function emojiEncode($str)
{
    preg_match_all('/[\xf0-\xf7].{3}/', $str, $array);
    foreach ($array[0] as $item) {
        $str = str_replace($item, '[[EMOJI:' . rawurlencode($item) . ']]', $str);
    }
    return $str;
}

/**
 * 清除emjor表情
 * @param $str
 * @return string
 */
function emojiRemove($str)
{
    preg_match_all('/[\xf0-\xf7].{3}/', $str, $array);
    foreach ($array[0] as $item) {
        $str = str_replace($item, "", $str);
    }
    return $str;
}